﻿using mozhi.smarterp.Finance.Accounts;
using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Accounts.Services;
using mozhi.smarterp.Finance.Basedatas;
using mozhi.smarterp.Finance.Basedatas.Repository;
using mozhi.smarterp.Finance.Basedatas.Services;
using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Finances.Repository;
using mozhi.smarterp.Finance.Finances.Services;
using mozhi.smarterp.Finance.Querys;
using mozhi.smarterp.Finance.Reports;
using Mozhi.Abp.Core.Extensions;
using Mozhi.Abp.Domain.BasicData;
using Mozhi.Abp.Domain.BasicData.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace mozhi.smarterp.Finance
{
    public abstract class ReportAppService : ApplicationService
    {
        protected IAccountRepository _accountRepository;
        protected IDimensionGroupValueRepository _dimensionGroupValueRepository;
        protected ICurrencyRepository _currencyRepository;
        protected IOrganizationRepository _organizationRepository;
        protected ISettlementRepository _settlementRepository;
        protected IAccountBalanceRepository _accountBalanceRepository;
        protected AccountBalanceManager _accountBalanceManager;
        protected DimensionGroupValueManager _dimensionGroupValueManager;

        public ReportAppService(IAccountRepository accountRepository, IDimensionGroupValueRepository dimensionGroupValueRepository,
            ICurrencyRepository currencyRepository, ISettlementRepository settlementRepository, IAccountBalanceRepository accountBalanceRepository,
            AccountBalanceManager accountBalanceManager, DimensionGroupValueManager dimensionGroupValueManager,
            IOrganizationRepository organizationRepository)
        {
            _accountRepository = accountRepository;
            _dimensionGroupValueRepository = dimensionGroupValueRepository;
            _currencyRepository = currencyRepository;
            _organizationRepository = organizationRepository;
            _settlementRepository = settlementRepository;
            _accountBalanceRepository = accountBalanceRepository;
            _accountBalanceManager = accountBalanceManager;
            _dimensionGroupValueManager = dimensionGroupValueManager;
        }

        public virtual async Task<List<AccountBalance>> GetAccountBalancesAsync(ReportQueryBase query)
        {
            List<AccountBalance> balances = new List<AccountBalance>();

            var opengingPeriod = (await GetOrganizationAsync()).ActivatedDate?.ToPeriod();

            if (!opengingPeriod.HasValue)
                return balances;

            if (query.StartPeriod == 0 || query.EndPeriod == 0 || query.EndPeriod < opengingPeriod.Value)
                return balances;

            query.StartPeriod = query.StartPeriod <= opengingPeriod.Value ? opengingPeriod.Value : query.StartPeriod;

            var lastSettlementPeriod = await _settlementRepository.GetLastClosePeriod();

            //未完成初始化
            if (lastSettlementPeriod == 0 || lastSettlementPeriod < opengingPeriod.Value.ToPrePeriod())
                return balances;

            var balanceQuery = new AccountBalanceQuery();
            balanceQuery.StartPeriod = query.StartPeriod;
            balanceQuery.EndPeriod = query.EndPeriod;
            balanceQuery.IncludeDimension = query.IncludeDimension ?? false;
            balanceQuery.IncludeCurrency = query.IncludeCurrency ?? false;

            balanceQuery.AccountIds = query.AccountId.HasValue ? new List<Guid> { query.AccountId.Value } : balanceQuery.AccountIds;
            balanceQuery.AccountIds = query.AccountIds != null ? query.AccountIds : balanceQuery.AccountIds;


            //查询期间在结账期间内，直接查询余额
            if (query.EndPeriod <= lastSettlementPeriod)
                balances = await _accountBalanceRepository.FindAsync(balanceQuery);
            else if (query.EndPeriod > lastSettlementPeriod)
            {
                //只有开始期间小于最后结账期间，才会有已结账期间的余额
                var balancesInClosePeriod = query.StartPeriod <= lastSettlementPeriod ? await _accountBalanceRepository.FindAsync(balanceQuery) : new List<AccountBalance>();

                var balancesInUnclosePeriod = await _accountBalanceManager.GetUnClosePeriodBalances(query.EndPeriod,
                    query.IncludeDimension.HasValue ? query.IncludeDimension.Value : false,
                    query.IncludeCurrency.HasValue ? query.IncludeCurrency.Value : false,
                    query.IncludeUnApproveJournal.HasValue ? query.IncludeUnApproveJournal.Value : false);

                balances.AddRange(balancesInClosePeriod);
                balances.AddRange(balancesInUnclosePeriod);
            }

            return balances;
        }


        #region
        protected string ReloadAccountName(string source, List<DimensionGroupValueItemDto> dimensionGroupValueItems)
        {
            if (dimensionGroupValueItems == null)
                return source;

            if (dimensionGroupValueItems.Count == 0)
                return $"{source}_未指定";

            var values = dimensionGroupValueItems.Where(x => !x.Label.IsNullOrEmpty()).Select(x => x.Label).ToList();

            return $"{source}_{string.Join("_", values)}";
        }


        protected async Task<List<AccountBalanceReportDto>> ConvertToBalanceReportDto(List<AccountBalance> balances)
        {
            //var result = new List<AccountBalanceReportDto>();

            //var currencyIds = balances.Where(x => x.CurrencyId.HasValue).Select(x => x.CurrencyId.Value).Distinct().ToList();

            //var currenys = new List<Currency>();// await _currencyRepository.GetAsync(new PageQuery() { Ids = currencyIds, PageIndex = 1, PageSize = int.MaxValue });

            //var dimensionGroupValueIds = balances.Where(x => x.DimensionGroupValueId.HasValue).Select(x => x.DimensionGroupValueId.Value).Distinct().ToList();

            //var dimensionGroupValues = await _dimensionGroupValueManager.GetDimensionGroupValues(dimensionGroupValueIds);

            //var accountIds = balances.Select(x => x.AccountId).Distinct().ToList();

            //var accounts = await _accountRepository.FindAsync(new AccountQuery() { Ids = accountIds });

            //foreach (var balance in balances)
            //{
            //    var matchAccount = accounts.FirstOrDefault(x => x.Id == balance.AccountId);

            //    var matchDimensionGroupValue = dimensionGroupValues.FirstOrDefault(x => x.Id == balance.DimensionGroupValueId);

            //    var row = new AccountBalanceReportDto();
            //    row.AccountId = balance.AccountId;
            //    row.Id = matchAccount?.Id;
            //    row.ParentId = matchAccount?.ParentId;

            //    row.AccountCode = matchAccount?.Code;
            //    row.AccountName = matchAccount?.Name;
            //    row.IsLeaf = matchAccount?.IsLeaf;
            //    row.Direction = matchAccount == null ? default : matchAccount.Direction;

            //    row.Period = balance.Period;
            //    row.DimensionGroupValueId = balance.DimensionGroupValueId;
            //    if (matchDimensionGroupValue != null && matchDimensionGroupValue.Items != null)
            //        row.DimensionGroupValueItems = ObjectMapper.Map<List<DimensionGroupValueItem>, List<DimensionGroupValueItemDto>>(matchDimensionGroupValue.Items);

            //    if (balance.DimensionGroupValueId.HasValue)
            //        row.AccountName = ReloadAccountName(row.AccountName, row.DimensionGroupValueItems);

            //    row.CurrencyId = balance.CurrencyId;
            //    row.CurrencyCode = currenys.FirstOrDefault(x => x.Id == balance.CurrencyId)?.Code;

            //    row.OpeningAmount = balance.OpeningAmount;
            //    row.OpeningAmountFr = balance.OpeningAmountFr;
            //    row.DebitAmount = balance.DebitAmount;
            //    row.DebitAmountFr = balance.DebitAmountFr;
            //    row.CreditAmount = balance.CreditAmount;
            //    row.CreditAmountFr = balance.CreditAmountFr;
            //    row.CurrentYearDebitAmount = balance.CurrentYearDebitAmount;
            //    row.CurrentYearDebitAmountFr = balance.CurrentYearDebitAmountFr;
            //    row.CurrentYearCreditAmount = balance.CurrentYearCreditAmount;
            //    row.CurrentYearCreditAmountFr = balance.CurrentYearCreditAmountFr;
            //    row.ClosingAmount = balance.ClosingAmount;
            //    row.ClosingAmountFr = balance.ClosingAmountFr;

            //    result.Add(row);
            //}

            //return result;
            throw new NotImplementedException();
        }


        protected virtual string GetSummary(int type)
        {
            var result = "";

            switch (type)
            {
                case 0:
                case 1:
                    result = "期初余额";
                    break;
                case 2:
                    result = "本期合计";
                    break;
                case 3:
                    result = "本年累计";
                    break;
            }
            return result;
        }


        protected virtual string GetBalanceDirection(int direction)
        {
            var result = "";

            switch (direction)
            {
                case 0:
                    result = "平";
                    break;
                case 1:
                    result = "借";
                    break;
                case -1:
                    result = "贷";
                    break;
            }
            return result;
        }

        protected virtual async Task<Organization> GetOrganizationAsync()
        {
            var organization = await _organizationRepository.GetAsync();

            return organization;
        }
        #endregion

    }


    public abstract class FinancialReportAppService : ReportAppService
    {
        private IEndPeriodProcessResultRepository _endPeriodProcessResultRepository;
        private IJournalRepository _journalRepository;
        private JournalManager _journalManager;

        protected FinancialReportAppService(IAccountRepository accountRepository, IDimensionGroupValueRepository dimensionGroupValueRepository, ICurrencyRepository currencyRepository,
            ISettlementRepository settlementRepository, IAccountBalanceRepository accountBalanceRepository, AccountBalanceManager accountBalanceManager, DimensionGroupValueManager dimensionGroupValueManager,
            IOrganizationRepository organizationRepository, IEndPeriodProcessResultRepository endPeriodProcessResultRepository, IJournalRepository journalRepository, JournalManager journalManager) :
            base(accountRepository, dimensionGroupValueRepository, currencyRepository, settlementRepository, accountBalanceRepository, accountBalanceManager,
                dimensionGroupValueManager, organizationRepository)
        {
            _endPeriodProcessResultRepository = endPeriodProcessResultRepository;
            _journalRepository = journalRepository;
            _journalManager = journalManager;
        }

        /// <summary>
        /// 排除掉结账损益凭证的后的余额
        /// </summary>
        /// <param name="startPeriod"></param>
        /// <param name="endPeriod"></param>
        /// <param name="balances">这里的余额只能是每个科目一条的，即没有核算维度和没有币别的</param>
        /// <param name="includeUnApprove">是否包括未审核的结转损益凭证</param>
        /// <returns></returns>
        protected async Task ExcludeProfitLossJournal(List<Account> accounts, int startPeriod, int endPeriod, List<AccountBalance> balances, bool includeUnApprove)
        {
            var profitLossBalances = await GetProfitLossBalances(accounts, startPeriod, endPeriod, includeUnApprove);

            //没有结转损益凭证转换的余额
            if (profitLossBalances.Count == 0)
                return;

            //一条余额一条余额开始处理
            foreach (var balance in balances)
            {
                //这个地方不需要带期间，本年累计要把前面的期间都扣除
                var matchProfitLossBalances = profitLossBalances.Where(x => x.AccountId == balance.AccountId).ToList();

                if (matchProfitLossBalances.Count == 0)
                    continue;

                //本期发生额需要带期间

                var debitAmount = balance.DebitAmount - matchProfitLossBalances.Where(x => x.Period == balance.Period).Sum(x => x.DebitAmount.ToDecimal());
                var creditAmount = balance.CreditAmount - matchProfitLossBalances.Where(x => x.Period == balance.Period).Sum(x => x.CreditAmount.ToDecimal());

                balance.ChangeCurrentAmount(debitAmount, debitAmount, creditAmount, creditAmount);

                //本年累计不需要带期间
                var currentYearDebitAmount = balance.CurrentYearDebitAmount - matchProfitLossBalances.Where(x => x.Period <= balance.Period && x.DebitAmount.HasValue).Sum(x => x.DebitAmount.ToDecimal());
                var currentYearCreditAmount = balance.CurrentYearCreditAmount - matchProfitLossBalances.Where(x => x.Period <= balance.Period && x.CreditAmount.HasValue).Sum(x => x.CreditAmount).ToDecimal();

                balance.ChangeCurrentYearAmount(debitAmount, creditAmount);
            }
        }


        /// <summary>
        /// 获取结转损益凭证的余额
        /// </summary>
        /// <param name="accounts"></param>
        /// <returns></returns>
        protected async Task<List<AccountBalance>> GetProfitLossBalances(List<Account> accounts, int startPeriod, int endPeriod, bool includeUnApprove)
        {
            var result = new List<AccountBalance>();

            var profitLossJournalBalances = await GetEndPeriodProcessJournalBalanceAsync(startPeriod, endPeriod, EndPeriodProcessType.TransferProfitLoss, includeUnApprove);

            if (profitLossJournalBalances == null || profitLossJournalBalances.Count == 0)
                return result;

            var baseCurrencyId = (await GetOrganizationAsync()).StandardCurrencyId;

            foreach (var balance in profitLossJournalBalances)
            {
                await _accountBalanceManager.CalculateAsync(balance, result, accounts, null, baseCurrencyId.Value);
            }

            return result.Where(x => x.CurrencyId == null && x.DimensionGroupValueId == null).ToList();

        }


        /// <summary>
        /// 凭证转换成余额(这里的余额是包括币别和核算维度的，而且是叶子节点科目)
        /// </summary>
        /// <param name="period"></param>
        /// <param name="transferType"></param>
        /// <param name="includeUnApprove">是否包括未审核</param>
        /// <returns></returns>
        protected async Task<List<AccountBalance>> GetEndPeriodProcessJournalBalanceAsync(int startPeriod, int endPeriod, EndPeriodProcessType transferType, bool includeUnApprove = false)
        {
            //var result = new List<AccountBalance>();

            //var endPeriodProcessResults = await _endPeriodProcessResultRepository.FindAsync(new EndPeriodProcessResultQuery() { StartPeriod = startPeriod, EndPeriod = endPeriod, Type = transferType, IncludeDetail = true });

            //if (endPeriodProcessResults.Count == 0)
            //    return result;


            //foreach (var monthlyProcessResult in endPeriodProcessResults)
            //{
            //    if (!monthlyProcessResult.JournalId.HasValue)
            //        continue;

            //    var journalId = monthlyProcessResult.JournalId.Value;

            //    var journal = await _journalRepository.FindAsync(journalId);

            //    if (journal == null || (!includeUnApprove && journal.Approved != true))
            //        continue;

            //    result.AddRange(_journalManager.ConvertToBalance(journal));
            //}

            //return result;
            throw new NotImplementedException();
        }


        /// <summary>
        /// 获取报表项的金额
        /// </summary>
        /// <param name="fieldType">1发生额 2本年累计 3 年初数 4期末余额</param>
        /// <param name="reportItem"></param>
        /// <param name="balances"></param>
        /// <returns></returns>
        protected async Task<decimal?> GetReportItemAmount(int fieldType, FinancialReportItemDto reportItem, List<Account> accounts,
            List<AccountBalance> balances, List<FinancialReportItemDto> reportItems, int minPeriod = -1, int maxPeriod = -1)
        {
            decimal result = 0.00M;

            if (reportItem == null || reportItem.Settings == null || balances == null || balances.Count == 0)
                return result;

            foreach (var setting in reportItem.Settings)
            {
                decimal? amount = null;

                //前置条件校验 不通过，直接就是0，就不需要做加减了
                if (!(ValidateReportItemPreConditions(reportItem, setting, balances, accounts, fieldType)))
                    continue;


                if (setting.CalculateTarget.IndexOf("R") == 0)
                {
                    var reportNubmer = setting.CalculateTarget.Replace("R", "");

                    var matchReportItem = reportItems.FirstOrDefault(x => x.Number == reportNubmer);

                    //计算引用行的值
                    amount = reportItem != null ? await GetReportItemAmount(fieldType, matchReportItem, accounts, balances, reportItems) : 0;
                }
                else
                {
                    var matchAccount = GetReportItemSettingAccount(accounts, setting);

                    if (matchAccount == null)
                        continue;

                    var matchBalances = balances.Where(x => x.AccountId == matchAccount.Id).ToList();

                    amount = GetBalanceAmount(setting.ValueRuleType.HasValue ? setting.ValueRuleType.Value : 0, fieldType, matchAccount, matchBalances, minPeriod, maxPeriod);
                }


                //没有金额，或者金额为0，不处理
                if (!amount.HasValue || amount.Value == 0)
                    continue;

                if (setting.Operator == "+")
                    result += amount.Value;
                else if (setting.Operator == "-")
                    result -= amount.Value;
            }

            return result;
        }


        /// <summary>
        /// 校验报表设置的前置条件
        /// </summary>
        /// <param name="reportItem"></param>
        /// <param name="setting"></param>
        /// <param name="balances"></param>
        /// <param name="accounts"></param>
        /// <param name="fieldType"></param>
        /// <returns></returns>
        private bool ValidateReportItemPreConditions(FinancialReportItemDto reportItem, FinancialReportItemSettingDto setting, List<AccountBalance> balances, List<Account> accounts, int fieldType)
        {
            if (reportItem.ReportType == FinancialReportType.BalanceSheet)
            {
                return ValidateBalanceSheetReportItemPreConditions(reportItem, setting, balances, accounts, fieldType);
            }
            else if (reportItem.ReportType == FinancialReportType.StatementOfCashFlow)
            {
                return ValidateCashFlowReportItemPreConditions(reportItem, setting, balances, accounts, fieldType);
            }

            return true;

        }


        /// <summary>
        /// 校验报表项的前置条件
        /// </summary>
        /// <param name="reportItem"></param>
        /// <param name="balances"></param>
        /// <param name="fieldType">取值字段3年初 4期末</param>
        /// <returns></returns>
        private bool ValidateBalanceSheetReportItemPreConditions(FinancialReportItemDto reportItem, FinancialReportItemSettingDto setting, List<AccountBalance> balances, List<Account> accounts, int fieldType)
        {
            //校验企业会计准则的资产负债表库存项和预收账款项目，是否达到之前条件的标准
            if (reportItem.AccountingStandard != AccountingStandardType.BusinessEnterprises ||
                reportItem.ReportType != FinancialReportType.BalanceSheet ||
                reportItem.Settings == null)
            {
                return true;
            }

            //需要是库存和预收账款项目，并且项目配置的科目是5401或者5402
            if ((setting.FinancialReportItemCode != "1_102_10" && setting.FinancialReportItemCode != "1_102_40") ||
                (setting.CalculateTarget != "5401" && setting.CalculateTarget != "5402"))
                return true;


            //需要两个科目都在,只有一个就校验了
            if (!reportItem.Settings.Exists(x => x.CalculateTarget == "5401") || !reportItem.Settings.Exists(x => x.CalculateTarget == "5402"))
                return true;

            var account5401 = accounts.FirstOrDefault(x => x.Code == "5401");
            var account5402 = accounts.FirstOrDefault(x => x.Code == "5402");


            var balance5401 = account5401 == null ? null : balances.FirstOrDefault(x => x.AccountId == account5401.Id);
            var balance5402 = account5402 == null ? null : balances.FirstOrDefault(x => x.AccountId == account5402.Id);

            var amount5401 = fieldType == 3 ? balance5401?.OpeningAmount : balance5401?.ClosingAmount;
            var amount5402 = fieldType == 3 ? balance5402?.OpeningAmount : balance5402?.ClosingAmount;

            //库存需要5401>5402
            if (setting.FinancialReportItemCode == "1_102_10" && amount5401 <= amount5402)
                return false;

            //预收账款要5401<=5402
            if (setting.FinancialReportItemCode == "1_102_40" && amount5401 > amount5402)
                return false;

            return true;
        }

        /// <summary>
        /// 校验报表项的前置条件
        /// </summary>
        /// <param name="reportItem"></param>
        /// <param name="balances"></param>
        /// <param name="fieldType">取值字段3年初 4期末</param>
        /// <returns></returns>
        private bool ValidateCashFlowReportItemPreConditions(FinancialReportItemDto reportItem, FinancialReportItemSettingDto setting, List<AccountBalance> balances, List<Account> accounts, int fieldType)
        {

            if (reportItem.ReportType != FinancialReportType.StatementOfCashFlow || reportItem.Settings == null || !setting.Precondition.HasValue ||
                setting.CalculateTarget.IsNullOrEmpty())
                return true;

            var matchAccount = accounts.FirstOrDefault(x => x.Code.Replace(".", "") == setting.CalculateTarget.Replace(".", ""));

            var balance = matchAccount == null ? null : balances.FirstOrDefault(f => f.AccountId == matchAccount.Id);

            //没有余额
            if (balance == null)
                return false;

            //期初余额要大于期末余额
            if (setting.Precondition.Value == 1 && balance.OpeningAmount <= balance.ClosingAmount)
                return false;

            //期初余额要小于期末余额
            if (setting.Precondition.Value == 2 && balance.OpeningAmount >= balance.ClosingAmount)
                return false;

            return true;
        }

        /// <summary>
        /// 获取报表设置的科目信息
        /// </summary>
        /// <param name="accounts"></param>
        /// <param name="setting"></param>
        /// <returns></returns>
        protected Account GetReportItemSettingAccount(List<Account> accounts, FinancialReportItemSettingDto setting)
        {
            Account result = null;

            if (accounts == null || setting == null || setting.CalculateTarget.IsNullOrEmpty())
                return result;

            var settingCode = setting.CalculateTarget;

            result = accounts.FirstOrDefault(x => x.Code.Replace(".", "") == settingCode.Replace(".", ""));

            return result;
        }

        /// <summary>
        /// 获取月表的金额
        /// </summary>
        /// <param name="valueType">1 借方余额 2 贷方余额 3借方余额为正 4贷方余额为正 5借方余额为负 6贷方余额为负 9借方发生额  10贷方发生额 11期间净发生额</param>
        /// <param name="fieldType">取值字段 1 发生额 2 本年累计 3年初</param>
        /// <param name="balances"></param>
        /// <returns></returns>
        protected decimal? GetBalanceAmount(int valueType, int fieldType, Account account, List<AccountBalance> balances, int minPeriod = -1, int maxPeriod = -1)
        {
            decimal? result = null;

            switch (valueType)
            {
                case 1:
                    //借方余额的时候，如果不是借方科目，金额取0
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Debit ? result : 0.00M;
                    break;
                case 2:
                    //贷方余额的时候，如果不是贷方科目，金额取0
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Credit ? result : 0.00M;
                    break;
                case 3:
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Debit ? result : 0.00M;
                    result = result > 0 ? result : 0.00M;
                    break;
                case 4:
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Credit ? result : 0.00M;
                    result = result > 0 ? result : 0.00M;
                    break;
                case 5:
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Debit ? result : 0.00M;
                    result = result < 0 ? result : 0.00M;
                    break;
                case 6:
                    result = fieldType == 3 ? balances.Sum(x => x.OpeningAmount) : balances.Sum(x => x.ClosingAmount);
                    result = account.Direction == AccountDirectionType.Credit ? result : 0.00M;
                    result = result < 0 ? result : 0.00M;
                    break;
                case 9:
                    if (fieldType == 1)
                    {
                        result = balances.Sum(x => x.DebitAmount);
                    }
                    else if (fieldType == 2)
                    {
                        result = balances.Sum(x => x.CurrentYearDebitAmount);
                    }
                    break;
                case 10:
                    if (fieldType == 1)
                    {
                        result = balances.Sum(x => x.CreditAmount);
                    }
                    else if (fieldType == 2)
                    {
                        result = balances.Sum(x => x.CurrentYearCreditAmount);
                    }
                    break;
                case 11:
                    if (fieldType == 1)
                    {
                        result = account.Direction == AccountDirectionType.Debit ? balances.Sum(x => x.DebitAmount - x.CreditAmount) :
                            balances.Sum(x => x.CreditAmount - x.DebitAmount);
                    }
                    else if (fieldType == 2)
                    {
                        result = account.Direction == AccountDirectionType.Debit ? balances.Sum(x => x.CurrentYearDebitAmount - x.CurrentYearCreditAmount) :
                            balances.Sum(x => x.CurrentYearCreditAmount - x.CurrentYearDebitAmount);
                    }
                    break;
                // 期初余额
                case 12:
                    result = minPeriod == -1 ? balances.Sum(x => x.OpeningAmount) : balances.Where(x => x.Period == minPeriod).Sum(x => x.OpeningAmount);
                    break;
                //期末余额
                case 13:
                    result = maxPeriod == -1 ? balances.Sum(x => x.ClosingAmount) : balances.Where(x => x.Period == maxPeriod).Sum(x => x.ClosingAmount);
                    break;

            }

            return result;
        }
    }
}
